package pikasial.images;


import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.SortedSet;
import java.util.TreeSet;

import javax.swing.DefaultListModel;


public class PhotosListModel extends DefaultListModel {

	private static final long serialVersionUID = 3836461079270026658L;

	private SortedSet<PikImage> aAfficher;
	private final ImageContainer album;

	/** Pour comparer les images par date de modification. */
    public static final Comparator<PikImage> PAR_DATE_MODIF =
        new Comparator<PikImage>() {
            public int compare(final PikImage p1, final PikImage p2) {
            	long l1 = p1.getJavaFile().lastModified();
            	long l2 = p2.getJavaFile().lastModified();
            	int c = 0;
                if ( l1 < l2) {
                	c = -1;
                } else if (l1 == l2) {
                	c = PAR_CHEMIN.compare(p1, p2);
                } else c = 1;
                return c;
            }
    };

    /** Comparer deux photos en fonction de leur date de création (i.e.
     * jour ou elles ont été prises ==> données EXIF).
     */
    @Deprecated
    public static final Comparator<PikImage> PAR_DATE_CREATION =
    	new Comparator<PikImage>() {
    		public int compare(final PikImage p1,final PikImage p2) {
				return 0;
    		}
    };

    /** Comparateur standard par nom de fichier
     */
    public static final Comparator<PikImage> PAR_CHEMIN =
    	new Comparator<PikImage>() {
    	 	public int compare(final PikImage p1,final PikImage p2) {
    	 		int i = p1.getPath().toLowerCase().compareTo(p2.getPath().toLowerCase());
    	 		return i;
    	 	}
     };


    /* ----Constructeurs---- */

	public PhotosListModel(ImageContainer im) {
		this(im,PAR_CHEMIN);
	}

	public PhotosListModel(ImageContainer ic,Comparator<PikImage> comp) {
		album = ic;
//		album.addObserver(this);
		aAfficher = Collections.synchronizedSortedSet(new TreeSet<PikImage>(comp));
	}

	/* ----Méthodes---- */

	public ImageContainer getAlbum() { return album; }

	public synchronized void addImage(PikImage pik) {
		int oldSize = aAfficher.size();
		aAfficher.add(pik);
		fireContentsChanged(this,(oldSize==0)?0:oldSize-1,oldSize);
	}

	public void removeImage(int index) {
		aAfficher.remove(index);
		fireIntervalRemoved(this,index,index);
	}

	public void removeImage(PikImage pik) {
		int i = 0;
		PikImage p;
		java.util.Iterator<PikImage> iter = aAfficher.iterator();
		while (iter.hasNext()) {
			p = iter.next();
			if (p == pik) {
				iter.remove();
				break;
			}
			i++;
		}
		fireIntervalRemoved(this,i,i);
	}

	public void synchroniserAvecAlbum() {
		int s = getSize();
		aAfficher.clear();
		if (album != null)
			aAfficher.addAll(album.getAllImages());
		fireContentsChanged(this,0,(s==0)?0:(getSize()-1));
	}

	public synchronized Object getElementAt(int index) {
		int i=0;
		PikImage p = null;
		for (PikImage pik : aAfficher) {
			if (i++ == index) {
				p = pik;
				break;
			}
		}
		return p;
	}

	public int getSize() {
		return aAfficher.size();
	}

	public Collection<PikImage> getImagesToDisplay() { return aAfficher; }


	public void trierPar(Comparator<PikImage> comp) {
		if (aAfficher.comparator() != comp && comp != null) {
			int s = getSize();
			Collection<PikImage> collec = getImagesToDisplay();
			aAfficher = Collections.synchronizedSortedSet(
					new TreeSet<PikImage>(comp));
			aAfficher.addAll(collec);
			fireContentsChanged(this,0,(s==0)?0:(getSize()-1));
		}
	}

	public synchronized void rechercherNom(String exp) {
		java.util.Iterator<PikImage> iter = aAfficher.iterator();
		PikImage pik;
		while (iter.hasNext()) {
			pik = iter.next();
			if (!pik.getName().toLowerCase().contains(exp.toLowerCase()))
				iter.remove();
		}
		fireContentsChanged(this,0,getSize()-1);
	}

	public void rechercherDate(Date date, boolean searchAfter) {
		long jour = date.getTime() / 86400000; // On récupère la date (le jour)
		if (searchAfter) {
			for (PikImage pik : aAfficher) {
				if ((pik.getDateModification().getTime() / 86400000) < jour) {
					removeImage(pik);
				}
			}
		} else {
			for (PikImage pik : aAfficher) {
				if ((pik.getDateModification().getTime() / 86400000) != jour) {
					removeImage(pik);
				}
			}
		}
		fireContentsChanged(this,0,getSize()-1);
	}

}
